/*

Contributors:

KR	Kisamin Resident
CJ	Chant Juran
EP	Erika Penucca

Changelog:

	27JUN2012	EP	Added sound (start in this script, stop in the other
					Set afterburner factor to 3
					Changed helpfile in sit control
	27JUN2013	CJ	Set rotation to 130
				KR	Set the script so that it forces phantom upon start
					Optimized the control functions to remove the mouse click code since we were not taking
					control of the mouse button.  Since the mouse click could not ever arrive, checking for it
					was wasting time.
					Used a different commenting style on the banking code so that it is obviously commented out
					Added comments to my previous work
	9.5			KR	Removed some unused variables and constants.
	9.9			KR	Removed references to the armed variable - it wasn't actually being used.
					Added a "die by date" function.

	-------------------- 9.11 released as Version 1.0 on July 15, 2012 (no changes to FlightCore since 9.9)
*/

string k_sDieDate = "2012-09-15";	// Do not accept rezzing after this date.  A plane will refuse to rezz or will delete itself on or after this date
// string k_sDieDate = "";			// Comment out the above line and uncomment this one to turn off auto-die

float k_fFwdThrust = 100.0;		//  Forward thrust motor force maximum
float k_fLateralThrust = 8.0;   //  Lateral
float k_fVerticalThrust = 14.0;	//  Hover thrust
float k_fFwdForce = 0.0;
float k_fRotationalImpulse = 140.0; // Impulse used to roll the plane.
float k_fInitialThrottleSetting = 0.10;

// Other varables
key g_kCurrentPilot = NULL_KEY;  // the key of the pilot passed from the sit and control script

float g_fMotorX = k_fInitialThrottleSetting; // PERCENTAGES of MOTOR THRUST
float g_fMotorY = 0.0;
float g_fMotorZ = 0.0;

// integer g_iArmed = 0;
integer g_iRollMode = TRUE;	// Set to true to start in roll mode.
integer k_iIsPlane = TRUE; // Whether there is even a roll mode available

list	g_lGearLinks = [];	// KR9.7 this list holds the link number of the various landing gear prims.

// STATES

checkDieDate () {
	list l_lParts = llParseString2List (llGetDate (), ["-"], []);
	integer l_iCurrentYear = (integer)llList2String (l_lParts, 0);
	integer l_iCurrentMonth = (integer)llList2String (l_lParts, 1);
	integer l_iCurrentDay = (integer)llList2String (l_lParts, 2);

	list l_lToDieParts = llParseString2List (k_sDieDate, ["-"], []);
	integer l_iDieYear = (integer)llList2String (l_lToDieParts, 0);
	integer l_iDieMonth = (integer)llList2String (l_lToDieParts, 1);
	integer l_iDieDay = (integer)llList2String (l_lToDieParts, 2);

	if (l_iCurrentYear > l_iDieYear)
		llDie ();

	if (l_iCurrentYear == l_iDieYear &&
		l_iCurrentMonth > l_iDieMonth)
		llDie ();

	if (l_iCurrentYear == l_iDieYear &&
		l_iCurrentMonth == l_iDieMonth &&
		l_iCurrentDay >= l_iDieDay)
		llDie ();
}

default {

	state_entry() {
		llSetStatus (STATUS_PHYSICS, FALSE);
		llSetStatus(STATUS_PHANTOM, TRUE);
		llSetStatus(STATUS_BLOCK_GRAB, TRUE);

		llSetVehicleType(VEHICLE_TYPE_SLED);

		llRemoveVehicleFlags(-1);
		llSetVehicleFlags(VEHICLE_FLAG_HOVER_UP_ONLY);
		llSetVehicleFlags(VEHICLE_FLAG_MOUSELOOK_STEER);
		llSetVehicleFlags(VEHICLE_FLAG_LIMIT_ROLL_ONLY);

		llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.0);
		llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 900.0);

		llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.0);
		llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 900.0);

		llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 0.25);  //  ------------- 1.5
		llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 1.0);

		llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.05);
		llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.01);

		llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, <0.0, 8.0, 7.0> ); // Required for mouselookKR001: WHY is this required???

		llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <60.0, 1.0, 30.0>);
		llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0.0, 0.0, 0.0>);

		llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, 0.0);
		llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0);
		llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 9000.0);

		llSetVehicleFloatParam(VEHICLE_BUOYANCY, 1.00); // We floats, we does

		if (k_iIsPlane) {
		  llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.5); // We be upright, but not uptight
		  llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 900.0);
		} else {
		  llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.5); // We be upright, but not uptight
		  llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 2.0);
		}

		// If we're a plane then we start in roll mode.  If we're a helo, the we start in strafe mode (and
		// can't go into roll mode)

		g_iRollMode = k_iIsPlane;
	}

	link_message(integer in_iSource, integer in_iNum, string in_sMessage, key in_kKey) {
		// KR001: Switch from strafe to roll mode or vice verce
		// 9.5 KR:  Added the vertical attractor when not in roll mode, remove it when in roll mode. 
		//			I hope this works like I think it will.
		if (in_sMessage == "roll" && k_iIsPlane ) {
			g_iRollMode = !g_iRollMode;
			if (g_iRollMode)
				llSetVehicleFloatParam (VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 900.0);
			else
				llSetVehicleFloatParam (VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 2.0);
		} else if ( (in_sMessage == "pilot") && (in_kKey == NULL_KEY) ) {
			llSetStatus (STATUS_PHYSICS, FALSE);
			llSetStatus (STATUS_PHANTOM, TRUE);
			llReleaseControls ();

			vector l_vCurrentRotation = llRot2Euler (llGetRootRotation ());
			llSetRot (llEuler2Rot (<0.0, 0.0, l_vCurrentRotation.z>));

			llResetScript();
		} else if( ( in_sMessage == "pilot" ) && (in_kKey != NULL_KEY) ) {
			g_fMotorX = k_fInitialThrottleSetting; // PERCENTAGES of MOTOR THRUST
			g_fMotorY = 0.0;
			g_fMotorZ = 0.0;
			g_kCurrentPilot = in_kKey;
			llRequestPermissions(g_kCurrentPilot, PERMISSION_TAKE_CONTROLS);
			//  ------------------------------------------------------------------------*** STARTUP
			llSetStatus(STATUS_BLOCK_GRAB, TRUE);
			llSetStatus (STATUS_PHANTOM, TRUE);
			llSetStatus (STATUS_PHYSICS, TRUE);
		} else if ((in_sMessage == "r")) {
			g_fMotorX = (float)in_iNum / 10.;

			// KR9.4 As per Erika, if throttle is set to 1, plane should NOT be phantom.
			// KR9.7 simplified the script a little bit by using the comparison instead of hard coded TRUE or FALSE

			llSetStatus (STATUS_PHANTOM, in_iNum != 1);
		}
	}

	run_time_permissions(integer in_iPermissions) {
		if(in_iPermissions & (PERMISSION_TAKE_CONTROLS))
			llTakeControls(CONTROL_FWD
										| CONTROL_BACK
										| CONTROL_RIGHT
										| CONTROL_LEFT
										| CONTROL_ROT_RIGHT
										| CONTROL_ROT_LEFT
										| CONTROL_UP
										| CONTROL_DOWN,
							TRUE, FALSE);
		else
			llUnSit(g_kCurrentPilot);
	}

	control(key in_kUser, integer in_iLevel, integer in_iEdge) {
		// CONTROLS -------- Y-AXIS THRUST

		g_fMotorY = 0;
		if(in_iLevel & (CONTROL_ROT_RIGHT | CONTROL_RIGHT)) {
			if (g_iRollMode)
				llApplyRotationalImpulse (<k_fRotationalImpulse, 0.0, 0.0>, TRUE);
			else
				g_fMotorY = -1.0;
		} else if(in_iLevel & (CONTROL_ROT_LEFT | CONTROL_LEFT)) {
			if (g_iRollMode)
				llApplyRotationalImpulse (<-k_fRotationalImpulse, 0.0, 0.0>, TRUE);
			else
				g_fMotorY = 1.0;
		}


		// CONTROLS -------- X-AXIS THRUST=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= FORWARD THROTTLE

		float l_fAppliedMotor_x = 0.0;

		if( (in_iLevel & CONTROL_FWD) && (in_iLevel & CONTROL_BACK) ) //FWD and BACK at once
			l_fAppliedMotor_x = 2.5;
		else if( (in_iLevel & CONTROL_FWD))
			l_fAppliedMotor_x = g_fMotorX;
		else if (in_iLevel & CONTROL_BACK)
			l_fAppliedMotor_x = -g_fMotorX;

		// CONTROLS -------- Z-AXIS THRUST

		g_fMotorZ = 0;
		if( (in_iLevel & CONTROL_UP))
			g_fMotorZ = 1.0;

		if ((in_iLevel & CONTROL_DOWN))
			g_fMotorZ = -0.8;

		if (g_fMotorX > 1.0)
			l_fAppliedMotor_x = 1.0;// regular limiter

		if ( (l_fAppliedMotor_x > -0.05) && (l_fAppliedMotor_x < 0.05) )
			l_fAppliedMotor_x = 0.0;

		float motorx;
		vector motor = <k_fFwdThrust * l_fAppliedMotor_x,
		k_fLateralThrust * g_fMotorY,
		k_fVerticalThrust * g_fMotorZ>;

		//Apply the linear motors
		if(g_fMotorX == 1.1)
			llApplyImpulse(<1500,0,0>, TRUE);
		else {
			llSetForce(<l_fAppliedMotor_x * k_fFwdForce,0,0>, TRUE);
			llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, motor);
		}
	}

	on_rez(integer in_iParameter) {
		if (k_sDieDate != "") {
			checkDieDate ();
			llSetTimerEvent ( 3600. * 24. );
		}

		llResetScript();
	}

	timer () {
		checkDieDate ();
	}
}
